#include <iostream>
#include <string>
#include <memory>
#include <utility>

using namespace std;

class ShareResource {
public:
    template<typename... Args>
    explicit ShareResource(Args&&... args) 
        : m_resource(make_shared<string>(std::forward<Args>(args)...)) {}

    ShareResource(ShareResource&& other) noexcept = default;
    
    ShareResource(const ShareResource& other) = default;
    
    ShareResource& operator=(ShareResource&& other) noexcept = default;
    
    ShareResource& operator=(const ShareResource& other) = default;

    ~ShareResource() = default;

    void read() const {
        cout << "读取内容: " << *m_resource << endl;
        cout << "引用计数: " << m_resource.use_count() << endl;
    }

    void write(const char* str) {
        cout << "写入前引用计数: " << m_resource.use_count() << endl;
        ensure_unique();
        *m_resource += str;
        cout << "写入后引用计数: " << m_resource.use_count() << endl;
    }

    void setContent(const char* str) {
        cout << "设置内容前引用计数: " << m_resource.use_count() << endl;
        ensure_unique();
        *m_resource = str;
        cout << "设置内容后引用计数: " << m_resource.use_count() << endl;
    }

    const string& getContent() const { 
        return *m_resource; 
    }

    ShareResource& operator+=(const char* str) {
        write(str);
        return *this;
    }

private:
    void ensure_unique() {
        if (m_resource.use_count() > 1) {
            m_resource = make_shared<string>(*m_resource);
        }
    }

    shared_ptr<string> m_resource;
};    

int main() 
{
    ShareResource r1("abc");
    ShareResource r2(std::string("def"));
    ShareResource r3(r1);
    
    cout << "初始资源状态:" << endl;
    r1.read();
    r2.read();
    r3.read();

    // 测试拷贝构造和写时拷贝
    cout << "\n拷贝构造后修改r3:" << endl;
    r3.write("hello");
    r3.read();
    r1.read();

    // 测试移动语义
    ShareResource r4(std::move(r2));
    cout << "\n移动构造后r4状态:" << endl;
    r4.read();
    
    // 测试赋值运算符
    r1 = r3;
    cout << "\n赋值操作后r1状态:" << endl;
    r1.read();

    // 测试+=运算符
    r1 += " world";
    cout << "\n使用+=运算符后r1状态:" << endl;
    r1.read();

    // 测试设置新内容
    cout << "\n设置新内容后:" << endl;
    r1.setContent("全新内容");
    r1.read();
    r3.read();

    return 0;
}    